import React from 'react';
import BaseFormItem from "../Base/BaseFormItem";
import ObjectSelect from "../ObjectBox/ObjectSelect";
import PropTypes from "prop-types";
import {isArray, isEmpty, isFunction, isString, keys, pick, trim} from "lodash-es";
import FinderModal from "../FinderModal";
import FinderHelper from "./FinderHelper";
import FinderCache from "./FinderCache";
import {getRandomKey, isObjectValEqual, QueryFilter} from "jh-utils";
// import MetaFieldFinderModal from "../FinderModal/MetaFieldFinderModal";
// import ResTargetFinderModal from "../FinderModal/ResTargetFinderModal";
// import ResItemFinderModal from "../FinderModal/ResItemFinderModal";

const staticProps = {
    finderCode: PropTypes.string,
    appCode: PropTypes.string,
    /**
     * 请求“查找器-配置信息”的方法
     * @type {function(ajaxData: {}): Promise}
     */
    fetchConf: PropTypes.func,
};

/**
 * 查找器-下拉框
 */
export default class FinderSelect extends BaseFormItem {
    Comp = FinderSelectBase;
}

/**
 * 查找器-下拉框
 */
export class FinderSelectBase extends ObjectSelect {

    static propTypes = {
        ...ObjectSelect.propTypes,
        ...staticProps
    };

    static defaultProps = {
        ...ObjectSelect.defaultProps,
        // defaultActiveFirstOption: false, // 是否默认高亮第一个选项。
        filterOption: false,
        needMenu: true,
        needMenuBtn: true,
        readOnly: false
    };

    moreCommonProps() {
        return [...super.moreCommonProps(), ...keys(staticProps)]
    }

    /**
     * 查找器的 appCode
     * @return {*}
     */
    get appCode4Finder() {
        return this.finderHelper.getAppCode4Finder();
    }

    /**
     * 查找器-配置
     * @type {{}}
     */
    set finderConf(value) {
        FinderCache.addConfCache(this.getPropsByName('finderCode'), value);
    }

    get finderConf() {
        return FinderCache.getConfCache(this.getPropsByName('finderCode'));
    }

    randomKey = getRandomKey();

    /**
     * QueryFilter 过滤器
     * @type { QueryFilter | {}}
     */
    filter = {};
    lastFetchId = 0;
    queryFields = [];
    /**
     * 是否以 queryFields 设置的字段为准，来查询数据。
     *  true: 查询的数据只会有 queryFields 设置了的字段。
     *  false: 查询的数据含有该查找器对应模型的所有默认字段
     * @type {boolean}
     */
    splitQuery = false;

    searchData = {
        fuzzyMatch: 'code,name,spellCode',
        search: '',
        filterData: {}
    };

    /**
     * 弹框组件的实例
     * @type { FinderModal | null}
     */
    modalIns = null;

    constructor(props) {
        super(props);
        this.finderHelper = new FinderHelper(this);
    }

    componentDidMount() {
        super.componentDidMount();
        this._tempFunc();
    }

    componentDidUpdate(prevProps, prevState) {
        super.componentDidUpdate && super.componentDidUpdate(prevProps, prevState);

        // 如果 finderCode 有变，则再次获取 finderConf
        if (!isObjectValEqual(this.compMoreProps, prevState.compMoreProps, ['finderCode'])) {
            this._tempFunc();
        }
    }

    componentWillUnmount() {
        super.componentWillUnmount();

        const finderCode = this.getPropsByName('finderCode');
        if (finderCode) {
            FinderCache.removeLoadingIns(finderCode, this.randomKey);
        }
    }

    /**
     * 点击右侧菜单之后的回调
     */
    hdlClickMenu() {
        this._tempFunc(() => {
            this.setState({isShowModal: true});
        });
    }

    hdlClickSelect(open) {
        this._tempFunc(() => {
            // 如果需要下拉框，才执行默认逻辑。否则，打开弹框
            if (this.getPropsByName('needDropdown')) {
                super.hdlClickSelect(open);
            } else if (this.getPropsByName('needMenu')) {
                this.hdlClickMenu();
            }
        });
    }

    fetchData() {
        this._tempFunc(() => {
            this.fetchListData();
        });
    }

    _tempFunc(cb) {
        // console.log('FinderSelectBase_tempFunc')
        // 执行“通过 addEditBeforeHandler 设置”的回调
        this.runBeforeCbs();

        if (!this.canFetchData) return;

        let finderCode = this.getPropsByName('finderCode');

        if (isEmpty(finderCode)) return;

        // 先获取查找器配置，然后请求列表数据
        this.finderHelper.getFinderConf(() => {
            this.setPropsByConf();
            cb && cb();
        });
    }

    /**
     * 请求列表数据
     */
    fetchListData() {
        this.searchData.search = this.state.inputVal;
        const reObj = this.finderHelper.getAjaxData4List({pageSize: 40, current: 1});

        if (false === reObj) return false;

        const {ajaxData, fetchFunc} = reObj;

        this.setState({loading: true});
        this.lastFetchId += 1;
        const fetchId = this.lastFetchId;
        const fetchReturn = fetchFunc(ajaxData, {}, this);

        if (fetchReturn instanceof Promise) {
            fetchReturn.then((rsp) => {

                if (fetchId !== this.lastFetchId) {
                    // 控制请求时序
                    return rsp;
                }

                let newList = [];

                if (rsp && rsp.status === 200) {
                    const rspData = rsp.data;
                    newList = isArray(rspData) ? rspData : (
                        isArray(rspData.results) ? rspData.results : []
                    );
                }

                this.setState({
                    list: newList,
                    loading: false
                }, () => {
                    this.runPropsFunc('onDataLoad')(newList);
                });
                return rsp;
            });
        } else {
            this.setState({loading: false});
        }
    }

    /**
     * 根据查找器配置（finderConf）更新属性值
     */
    setPropsByConf() {
        const $ins = this;
        const {appins, renderItem} = $ins.getProps();
        const finderConf = $ins.finderConf;
        let appDendroid = this.getPropsByName('appDendroid') || this.finderConf.appDendroid;
        let needFresh = isFunction(this.finderHelper.getFetchListFunc());
        let appCode = this.appCode4Finder;

        const newProps = {
            finderName: finderConf.name,
            finderCode: finderConf.finderCode,
            descField: finderConf.descField,
            // needAdd: true,
            // needList: true,
            // needRefresh: true,
            needAdd: !isEmpty(appCode),
            needList: !isEmpty(appCode),
            needRefresh: needFresh,
            // 选项卡显示的内容
            renderItem: isFunction(renderItem) ? renderItem : (optionData) => {
                const {labelField = 'name'} = $ins.finderConf;
                let optionText = optionData['name'] || optionData['code'];
                // 下拉列表显示字段,';'号分隔
                if (isString(labelField) && !isEmpty(labelField)) {
                    let fields = labelField.split(';');
                    let len = fields.length;
                    let tmpStr = '';
                    optionText = fields.map((v, k) => {
                        if (optionData[v]) {
                            tmpStr += `${optionData[v]}` || '';
                        }

                        if (k / 2 === 0) {
                            return <span key={k} className={len > 1 ? 'text-gray' : ''}>{optionData[v] || ''} </span>;
                        } else {
                            return optionData[v] || '';
                        }
                    });
                    if (trim(tmpStr) === '') {
                        optionText = optionData['code'];
                    }
                }
                return optionText;
            },
            // 选中后回显的内容
            renderOptionText: (optionData) => {
                const {descField = 'name'} = $ins.finderConf;
                let text = '';
                let tmpStr = '';
                // 值显示的字段,';'号分隔
                if (isString(descField) && !isEmpty(descField)) {
                    const fields = descField.split(';');
                    fields.forEach((v) => {
                        if (optionData[v]) {
                            tmpStr += `${optionData[v]}` || '';
                            text += `${optionData[v]} ` || ''
                        }
                    });
                }
                if (trim(tmpStr) === '') {
                    text = optionData['code'];
                }

                return text;
            },
            // 操作“下拉浮层底部”的按钮
            onDDFooterAction: ({type}) => {
                // console.log('onDDFooterAction', type);
                if (type === this.actionTypes.refresh) {
                    // 刷新
                    this.fetchData(true);
                } else {
                    this.setState({open: false}); // 关闭下拉浮层
                    const {onFinderAction} = this.getProps();

                    if (isFunction(onFinderAction)) {
                        const finderCode = this.getPropsByName('finderCode');
                        onFinderAction({type, appCode, finderCode, value: this.getValue(), compIns: this});
                        return;
                    }

                    if (appins && appins.onFinderAction) {
                        const finderCode = this.getPropsByName('finderCode');
                        appins.onFinderAction({type, appCode, finderCode, value: this.getValue(), compIns: this});
                    }
                }
            }
        };

        if (appDendroid) {
            newProps.needDropdown = false; // 如果是单表树状类型的查找器，则只能弹框选择
        }

        $ins.setCompProps(newProps);
    }

    chooseRender(props) {
        const {finderName, multi} = props;
        const {value} = this.state;
        const defaultSelectedRows = isArray(value) ? value : (
            !isEmpty(value) ? [value] : []
        );
        let fViewer = `${this.finderConf.viewer}`;

        if (isEmpty(fViewer)) {
            return null;
        }

        let FModal = FinderModal;

        // if (-1 < fViewer.indexOf('MetadataFieldFinderWindow')) {
        //     FModal = MetaFieldFinderModal;
        // } else if (-1 < fViewer.indexOf('ResTargetFinderModal')) {
        //     FModal = ResTargetFinderModal;
        // } else if (-1 < fViewer.indexOf('ResItemFinderModal')) {
        //     FModal = ResItemFinderModal;
        // }

        return (
            <FModal
                onRef={(ins) => {
                    this.modalIns = ins;
                }}
                defaultSelectedRows={defaultSelectedRows}
                multi={multi}
                title={finderName || '-'}
                visible={this.state.isShowModal}
                canFetchData={this.canFetchData}
                onOk={this.hdlChooseOk.bind(this)}
                onCancel={this.hdlChooseCancel.bind(this)}
                {...pick(props, ['appins', 'finderCode', 'appCode', 'javaType', 'filter', 'queryFields',
                    'fetchConf', 'fieldName', 'record', 'fetchList', 'referenceAppInfo', 'plural',
                    'rowIndex', 'belong'])}
                exeInMount={(compIns) => {
                    compIns.editBeforeCbs = this.editBeforeCbs;
                    props.exeInMount && props.exeInMount(compIns);
                }}
            />
        )
    }
}
